const db = require('../models');
const Post = db.Post;
const Tag = db.Tag;
const User = db.User;
const { Op } = require('sequelize');

/**
 * 文章服务层
 * 处理与文章相关的业务逻辑
 */
class PostService {
  /**
   * 创建新文章
   * @param {Object} postData - 文章数据
   * @param {Array} tagIds - 标签ID数组
   * @returns {Promise<Object>} 创建的文章对象
   */
  async create(postData, tagIds = []) {
    const transaction = await db.sequelize.transaction();
    
    try {
      // 创建文章
      const post = await Post.create(postData, { transaction });
      
      // 如果有标签，添加关联
      if (tagIds && tagIds.length > 0) {
        await post.addTags(tagIds, { transaction });
      }
      
      await transaction.commit();
      
      // 返回创建的文章（包含标签）
      return this.findById(post.id);
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 根据ID查找文章
   * @param {number} id - 文章ID
   * @returns {Promise<Object>} 文章对象
   */
  async findById(id) {
    return await Post.findByPk(id, {
      include: [
        {
          model: User,
          as: 'author',
          attributes: ['id', 'username', 'avatar']
        },
        {
          model: Tag,
          as: 'tags',
          through: { attributes: [] } // 不包含中间表字段
        }
      ]
    });
  }

  /**
   * 根据slug查找文章
   * @param {string} slug - 文章slug
   * @returns {Promise<Object>} 文章对象
   */
  async findBySlug(slug) {
    return await Post.findOne({
      where: { slug },
      include: [
        {
          model: User,
          as: 'author',
          attributes: ['id', 'username', 'avatar']
        },
        {
          model: Tag,
          as: 'tags',
          through: { attributes: [] }
        }
      ]
    });
  }

  /**
   * 获取文章列表
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 包含文章列表和总数的对象
   */
  async findAll(options = {}) {
    const { page = 1, limit = 10, status, userId, tagId, search } = options;
    
    const query = {
      where: {},
      include: [
        {
          model: User,
          as: 'author',
          attributes: ['id', 'username', 'avatar']
        },
        {
          model: Tag,
          as: 'tags',
          through: { attributes: [] }
        }
      ],
      order: [['createdAt', 'DESC']],
      offset: (page - 1) * limit,
      limit: parseInt(limit)
    };
    
    // 根据状态筛选
    if (status) {
      query.where.status = status;
    }
    
    // 根据用户ID筛选
    if (userId) {
      query.where.userId = userId;
    }
    
    // 根据标签ID筛选
    if (tagId) {
      query.include[1].where = { id: tagId };
    }
    
    // 搜索功能
    if (search) {
      query.where[Op.or] = [
        { title: { [Op.like]: `%${search}%` } },
        { content: { [Op.like]: `%${search}%` } }
      ];
    }
    
    // 获取总数和数据
    const { count, rows } = await Post.findAndCountAll(query);
    
    return {
      total: count,
      totalPages: Math.ceil(count / limit),
      currentPage: page,
      posts: rows
    };
  }

  /**
   * 更新文章
   * @param {number} id - 文章ID
   * @param {Object} postData - 更新的文章数据
   * @param {Array} tagIds - 标签ID数组
   * @returns {Promise<Object>} 更新后的文章对象
   */
  async update(id, postData, tagIds) {
    const transaction = await db.sequelize.transaction();
    
    try {
      // 更新文章基本信息
      await Post.update(postData, {
        where: { id },
        transaction
      });
      
      // 如果提供了标签，更新标签关联
      if (tagIds !== undefined) {
        const post = await Post.findByPk(id, { transaction });
        // 清除现有标签关联并添加新的关联
        await post.setTags(tagIds || [], { transaction });
      }
      
      await transaction.commit();
      
      // 返回更新后的文章
      return this.findById(id);
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 删除文章（软删除）
   * @param {number} id - 文章ID
   * @returns {Promise<number>} 删除的记录数
   */
  async delete(id) {
    return await Post.destroy({
      where: { id }
    });
  }

  /**
   * 增加文章浏览量
   * @param {number} id - 文章ID
   * @returns {Promise<Object>} 更新结果
   */
  async incrementViewCount(id) {
    return await Post.increment('viewCount', {
      by: 1,
      where: { id }
    });
  }

  /**
   * 获取热门文章
   * @param {number} limit - 限制数量
   * @returns {Promise<Array>} 热门文章列表
   */
  async getPopularPosts(limit = 5) {
    return await Post.findAll({
      where: { status: 'published' },
      order: [['viewCount', 'DESC']],
      limit,
      include: [
        {
          model: User,
          as: 'author',
          attributes: ['id', 'username', 'avatar']
        }
      ]
    });
  }
}

module.exports = new PostService();